<template>
	<div class="xy-dialog" v-if="realShowDialog" :style="{ opacity: showDialog ? '' : 0 }">
		<!-- 包裹层 -->
		<div
			class="xy-dialog-wrapper"
			:style="{ width }"
			:ref="refName"
			:class="[fullScreen ? 'fullScreen' : '']"
		>
			<!-- 标题栏 -->
			<div class="xy-dialog-title" :style="{ textAlign: center ? 'center' : '' }">
				{{ title }}
			</div>

			<!-- 关闭按钮 -->
			<div class="xy-dialog-close" v-if="showClose">
				<i class="el-icon-close" @click="closeDialog"></i>
			</div>

			<!-- dialog内容 -->
			<div class="xy-dialog-content">
				<slot></slot>
			</div>

			<!-- 底部组件 -->
			<div class="xy-dialog-footer" :style="{ textAlign: center ? 'center' : '' }">
				<!-- 默认按钮样式 -->
				<div class="xy-dialog-footer-default">
					<slot name="footer"></slot>
				</div>
			</div>
		</div>
	</div>
</template>

<script>
export default {
	name: 'XyDialog',
	props: {
		showDialog: {
			// 是否显示dialog
			type: Boolean,
			default: false
		},
		refName: {
			// 区分唯一的dialog 嵌套的时候区分不同的弹出层
			type: String,
			default: 'dialogWrapper'
		},
		width: {
			// 内容区域的宽度
			type: String,
			default: '50%'
		},
		title: {
			// 弹出层的标题
			type: String,
			default: '标题'
		},
		showClose: {
			// 是否展示关闭按钮
			type: Boolean,
			default: true
		},
		center: {
			// 标题和按钮居中展示
			type: Boolean,
			default: false
		},
		fullScreen: {
			// 全屏 dialog
			type: Boolean,
			default: false
		}
	},
	watch: {
		showDialog: {
			handler(newVal, oldVal) {
				// 检测 showDialog 变化运行动画效果
				if (this.showDialog) {
					// 去除打开时候的滚动条
					const BODY = document.querySelector('body');
					BODY.style.overflow = 'hidden';

					this.realShowDialog = true;
					this.init(true);
				} else {
					// 显示滚动条
					const BODY = document.querySelector('body');
					BODY.style.overflow = '';

					this.init(false);
				}
			},
			deep: true
		}
	},
	data() {
		return {
			realShowDialog: false
		};
	},
	methods: {
		// 初始化函数
		init(isShow) {
			this.$nextTick(() => {
				// dom 挂载后计算弹窗宽高
				const dialogWrapper = this.$refs[this.refName]; // 弹窗包裹层
				const dialogWidth = dialogWrapper.offsetWidth;
				const dialogHeight = dialogWrapper.offsetHeight;

				if (isShow) {
					// 展示
					this.showAnimation(dialogWrapper, dialogWidth, dialogHeight);
				} else {
					// 隐藏
					this.hideAnimation(dialogWrapper, dialogWidth, dialogHeight);
				}
			});
		},

		// 展示弹出层时执行的动画
		showAnimation(div, width, height) {
			div.style.transform = `translate(calc(50vw + ${width / 2}px), 
			calc(50vh + ${height / 2}px))`;

			setTimeout(() => {
				div.style.transition = 'transform .3s ease-in-out';

				div.style.transform = '';
			});
		},

		// 隐藏弹出层时执行的动画
		hideAnimation(div, width, height) {
			div.style.transform = `translate(calc(50vw + ${width / 2}px), 
			calc(50vh + ${height / 2}px))`;

			div.style.transition = 'transform .3s';

			setTimeout(() => {
				this.realShowDialog = false;
			}, 300);
		},

		// 关闭弹出层
		closeDialog() {
			this.$emit('update:showDialog', false);
		}
	}
};
</script>

<style lang="scss">
.xy-dialog {
	position: fixed;
	z-index: 100;
	width: 100%;
	height: 100%;
	top: 0;
	left: 0;
	background-color: rgba($color: #999, $alpha: 0.5);
	transition: opacity 0.3s;
	display: flex;
	justify-content: center;
	align-items: center;

	.fullScreen.xy-dialog-wrapper {
		width: 100% !important;
		height: 100% !important;
		box-sizing: border-box !important;
	}

	.xy-dialog-wrapper {
		background-color: #fff;
		padding: 60px 20px 20px 20px;
		border-radius: 5px;
		box-shadow: 0 0 3px rgb(209, 204, 204);
		position: relative;

		.xy-dialog-title {
			// cursor: move;
			position: absolute;
			box-sizing: border-box;
			color: #666;
			padding: 10px 20px;
			left: 0;
			top: 0;
			width: 100%;
			background-color: rgb(243, 241, 241);
			border-radius: 5px 5px 0 0;
			box-shadow: 0 1px 3px rgba($color: #a3a2a2, $alpha: 0.5);
		}

		.xy-dialog-close {
			position: absolute;
			right: 15px;
			top: 10px;
			cursor: pointer;

			i {
				color: rgb(130, 130, 131);

				&:hover {
					color: rgb(75, 164, 247);
				}
			}
		}

		.xy-dialog-footer {
			box-sizing: border-box;
			width: 100%;
			text-align: right;
			padding-top: 10px;
		}
	}
}
</style>